﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using VideoSeller.Business.Data;
using VideoSeller.Business.Data.Entities;
using VideoSeller.Business.Data.Enums;
using VideoSeller.Core.Configuration;
using VideoSeller.Core.Interfaces;

namespace VideoSeller.Business.Models
{
	public class OnlineContentModel : Repository<OnlineContent>
	{
		private readonly IDatabaseSettingsProvider _databaseSettingsProvider;
		private readonly OnlineCategorizationModel _onlineCategorizationModel;
		private readonly OnlineRatingModel _onlineRatingModel;
		private readonly TeamDocsModel _teamDocsModel;
		private readonly TeamChatModel _teamChatModel;
		private readonly TagModel _tagModel;
        private readonly OnlineContentClaimModel _onlineContentClaimModel;

        public OnlineContentModel(OnlineCategorizationModel onlineCategorizationModel, TagModel tagModel,
            OnlineRatingModel onlineRatingModel, IDatabaseSettingsProvider databaseSettingsProvider,
            TeamDocsModel teamDocsModel, TeamChatModel teamChatModel, OnlineContentClaimModel onlineContentClaimModel)
		{
			_onlineCategorizationModel = onlineCategorizationModel;
			_onlineRatingModel = onlineRatingModel;
			_databaseSettingsProvider = databaseSettingsProvider;
			_teamChatModel = teamChatModel;
			_teamDocsModel = teamDocsModel;
            _onlineContentClaimModel = onlineContentClaimModel;
	        _tagModel = tagModel;
		}
        public IEnumerable<OnlineContent> AllContent
        {
            get { return Table.Where(m => m.State > -1); }
        }
		public OnlineContent GetOnlineContent(int id)
		{
            return AllContent.SingleOrDefault(x => x.Id == id && !x.IsDraft);
		}
        public IEnumerable<OnlineContent> GetTopViews(int cnt, String type)
        {
            if (type == "A")
                return AllContent.OrderByDescending(m => m.ViewCntA).Take(cnt);
            if (type == "H")
                return AllContent.OrderByDescending(m => m.ViewCntH).Take(cnt);
            return AllContent.OrderByDescending(m => m.ViewCnt).Take(cnt);
            
        }

		public IEnumerable<OnlineContent> GetAll(Guid userId)
		{
            return (from content in AllContent
			        join category in DataContext.OnlineCategorizations on content.Id equals category.OnlineContentId
			        where !content.IsDraft && content.UserId == userId && !category.Category.Limited
			        select content).Distinct();
		}

		public IEnumerable<OnlineContent> GetAll(OnlineContentType onlineContentType)
		{
			UpdateAnnouncement();

			switch (onlineContentType)
			{
				case OnlineContentType.Announcement:
                    return (from content in AllContent
					        where !content.IsDraft && !content.Active && content.DownloadUrl == null
					        select content).Distinct();
				case OnlineContentType.Online:
                    return (from content in AllContent
					        where !content.IsDraft && content.Active
					        select content).Distinct();
				case OnlineContentType.History:
                    return (from content in AllContent
					        where !content.IsDraft && !content.Active && content.DownloadUrl != null
					        select content).Distinct();
			}

			return new List<OnlineContent>();
		}

		public IEnumerable<OnlineContent> GetAllWithoutLimited(OnlineContentType onlineContentType)
		{
			switch (onlineContentType)
			{
				case OnlineContentType.Announcement:
                    return (from content in AllContent
							join category in DataContext.OnlineCategorizations on content.Id equals category.OnlineContentId
							where !content.IsDraft && !content.Active && content.DownloadUrl == null && !category.Category.Limited
							select content).Distinct();
				case OnlineContentType.Online:
                    return (from content in AllContent
							join category in DataContext.OnlineCategorizations on content.Id equals category.OnlineContentId
							where !content.IsDraft && content.Active && !category.Category.Limited
							select content).Distinct();
				case OnlineContentType.History:
                    return (from content in AllContent
							join category in DataContext.OnlineCategorizations on content.Id equals category.OnlineContentId
							where !content.IsDraft && !content.Active && content.DownloadUrl != null && !category.Category.Limited
							select content).Distinct();
			}

			return new List<OnlineContent>();
		}

		public IEnumerable<OnlineContent> GetAll(Guid userId, OnlineContentType onlineContentType)
		{
			UpdateAnnouncement();

			switch (onlineContentType)
			{
				case OnlineContentType.Announcement:
				case OnlineContentType.Online:
                    return (from content in AllContent
					        join category in DataContext.OnlineCategorizations on content.Id equals category.OnlineContentId
					        where !content.IsDraft && content.UserId == userId && content.DownloadUrl == null && !category.Category.Limited
					        select content).Distinct();
				case OnlineContentType.History:
                    return (from content in AllContent
					        join category in DataContext.OnlineCategorizations on content.Id equals category.OnlineContentId
					        where !content.IsDraft && !content.Active && content.UserId == userId && content.DownloadUrl != null && !category.Category.Limited
					        select content).Distinct();
			}

			return new List<OnlineContent>();
		}

		public int GetOnlineCount(int categoryId)
		{
            return (from content in AllContent
					join category in DataContext.OnlineCategorizations on content.Id equals category.OnlineContentId
					where !content.IsDraft && content.Active && category.CategoryId == categoryId
					select content).Distinct().Count();
		}

		public void Refund(int onlineContentId)
		{
			var postingModel = IoC.Resolve<PostingModel>();
			var onlineContent = GetOnlineContent(onlineContentId);
			var messageRefundForIllegalContent = HttpContext.GetGlobalResourceObject("Common", "RefundForIllegalContent", CultureInfo.CurrentUICulture);
			var messageSubstractForIllegalContent = HttpContext.GetGlobalResourceObject("Common", "SubstractForIllegalContent", CultureInfo.CurrentUICulture);
			string message;

			foreach (var paid in onlineContent.Paids)
			{
				message = messageRefundForIllegalContent != null ? string.Format(messageRefundForIllegalContent.ToString(), paid.Value, onlineContent.Title) : string.Empty;
				postingModel.AddFinanceOperation(paid.UserId, paid.Value, FinanceOperation.RefundForIllegalContent, message);
			}

			message = messageSubstractForIllegalContent != null ? string.Format(messageSubstractForIllegalContent.ToString(), onlineContent.Paids.Sum(x => x.Value), onlineContent.Title) : string.Empty;
			postingModel.AddFinanceOperation(onlineContent.UserId, onlineContent.Paids.Sum(x => x.Value), FinanceOperation.SubstractForIllegalContent, message);
			DeleteContent(onlineContentId);
		}
        public void setContentDsc(int onlineContentId, String dsctext)
        {
            var onlineContent = GetOnlineContent(onlineContentId);
            if (onlineContent == null)
                return;
            onlineContent.CamParam = dsctext;
            SubmitAllChanges();
        }
		public int AddOnlineContent(OnlineContentItem contentItem, Guid userId)
		{
			var item = new OnlineContent
				{
					Title = contentItem.Name,
					Description = contentItem.Description,
					CamParam = contentItem.CamParam,
					BroadcastType = (short) contentItem.BroadcastType,
					ImageUrl = contentItem.ThumbnailFileUrl,
					Active = false,
					CreatedTime = DateTime.Now,
					UserId = userId,
					CountryId = contentItem.Country,
					Culture = contentItem.Culture,
					IsDraft = contentItem.IsDraft,
                    AutoHistory=contentItem.AutoHistory,
					VideoContentTypeValue = (short)contentItem.VideoContentType,
                    MaxHours = contentItem.MaxHours,
                    MaxUsers = contentItem.MaxUsers,
                    QualityString = contentItem.QualityString
				};

			if (contentItem.VideoContentType == VideoContentType.Free)
			{
				item.MinimalPrice = contentItem.Price;
			}
			else if (contentItem.VideoContentType == VideoContentType.Paid)
			{
				item.MinimalPrice = contentItem.Price;
				item.TeamCount = _databaseSettingsProvider.ConferenceMembersCount;
			}
			else if (contentItem.VideoContentType == VideoContentType.PaidGroups)
			{
				item.MinimalPrice = contentItem.Price;
				item.TeamCount = contentItem.TeamCount;
			}
            if (item.MinimalPrice < 0)
                item.MinimalPrice = 0;
			if (contentItem.BroadcastType == BroadcastType.Manually)
			{
				item.BroadcastDescription = contentItem.BroadcastDescription;
                item.BroadcastStart = (contentItem.StartDateTime == DateTime.MinValue) ? DateTime.Now : contentItem.StartDateTime; /*HPN change at 14.09.2013*/
			}
			else
			{
				item.BroadcastStart = contentItem.StartDateTime;
				item.BroadcastEnd = contentItem.EndDateTime;
			}

			if (!string.IsNullOrEmpty(contentItem.Password))
			{
				item.Password = contentItem.Password;
			}

			if (contentItem.Categories.Count > 0)
			{
				foreach (var category in contentItem.Categories)
				{
					item.OnlineCategorizations.Add(new OnlineCategorization {CategoryId = int.Parse(category)});
				}
			}

			if (contentItem.Tags.Count > 0)
			{
				foreach (var tag in contentItem.Tags)
				{
					var tagId = _tagModel.GetTag(tag);
					item.OnlineContentTags.Add(new OnlineContentTag {TagId = tagId.Id});
				}
			}

			if (contentItem.TeamDocumentsUrls.Count > 0 && contentItem.TeamDocumentsUrls.Count == contentItem.TeamDocumentsNames.Count)
			{
				for (var i = 0; i < contentItem.TeamDocumentsUrls.Count; i++)
				{
					var url = contentItem.TeamDocumentsUrls[i];
					var name = contentItem.TeamDocumentsNames[i];
					item.TeamDocs.Add(new TeamDoc {Name = name, Url = url});
				}
			}
            item.NeedMoney = needMoney(item.QualityString, item.VideoContentType.ToString(),
                  item.MaxUsers.HasValue ? item.MaxUsers.Value : 0,
                  item.MaxHours.HasValue ? item.MaxHours.Value : 0);

			Insert(item);

			return item.Id;
		}
        public void clearNeedMoney(int contentID)
        {
            var item = AllContent.SingleOrDefault(x => x.Id == contentID);
            item.NeedMoney = 0;
            SubmitAllChanges();

        }
        public decimal needMoney(String qualityString, String contentType, int maxUsers, int maxHours)
        {
            try
            {
                VideoSeller.Business.Models.SettingsModel sm = new Business.Models.SettingsModel();
                float mulQ = sm.CostForPar(sm.findQualityString(qualityString).KeyName);
                if (mulQ == 0) return (decimal)mulQ;
                mulQ = mulQ * sm.MaxViewerCntMult.Where(m => m.Key == maxUsers).FirstOrDefault().Value;
                if (mulQ == 0) return (decimal)mulQ;
                mulQ = mulQ * sm.MaxTimeMult.Where(m => m.Key == maxHours).FirstOrDefault().Value;
                if (mulQ == 0) return (decimal)mulQ;
                mulQ = mulQ * sm.ContentTypeMult.Where(m => m.Key == contentType).FirstOrDefault().Value;
                return (decimal)mulQ;
            }
            catch
            {
            }
            return 1000000000;
        }
		public void UpdateOnlineContent(OnlineContentItem contentItem, Guid userId)
		{
            var item = AllContent.SingleOrDefault(x => x.Id == contentItem.CreatedContentId);

			if (item != null)
			{
				item.Title = contentItem.Name;
				item.Description = contentItem.Description;
				item.CamParam = contentItem.CamParam;
				item.BroadcastType = (short) contentItem.BroadcastType;
				item.ImageUrl = contentItem.ThumbnailFileUrl;
				item.Active = false;
				item.UserId = userId;
				item.CountryId = contentItem.Country;
				item.Culture = contentItem.Culture;
				item.AutoHistory = contentItem.AutoHistory;
				item.VideoContentTypeValue = (short) contentItem.VideoContentType;
				item.IsDraft = false;
                item.MaxHours = contentItem.MaxHours;
                item.MaxUsers = contentItem.MaxUsers;
                item.QualityString = contentItem.QualityString;
                //
				if (contentItem.VideoContentType == VideoContentType.Free)
				{
					item.MinimalPrice = (contentItem.Price > 0) ? contentItem.Price: 0;
				}
				else if (contentItem.VideoContentType == VideoContentType.Paid)
				{
                    item.MinimalPrice = (contentItem.Price > 0) ? contentItem.Price : 0;
					item.TeamCount = _databaseSettingsProvider.ConferenceMembersCount;
				}
				else if (contentItem.VideoContentType == VideoContentType.PaidGroups)
				{
                    item.MinimalPrice = (contentItem.Price > 0) ? contentItem.Price : 0;
					item.TeamCount = contentItem.TeamCount;
				}

				if (contentItem.BroadcastType == BroadcastType.Manually)
				{
					item.BroadcastDescription = contentItem.BroadcastDescription;
					item.BroadcastStart = contentItem.StartDateTime;
				}
				else
				{
					item.BroadcastStart = contentItem.StartDateTime;
					item.BroadcastEnd = contentItem.EndDateTime;
				}

                if (!string.IsNullOrEmpty(contentItem.Password))
                {
                    item.Password = contentItem.Password;
                }
                else { item.Password = null; }

				if (contentItem.Categories.Count > 0)
				{
					_onlineCategorizationModel.DeleteAll(item.OnlineCategorizations);
					foreach (var category in contentItem.Categories)
					{
						item.OnlineCategorizations.Add(new OnlineCategorization { CategoryId = int.Parse(category) });
					}
				}

				if (contentItem.Tags.Count > 0)
				{
					_tagModel.DeleteAll(item.OnlineContentTags);
					foreach (var tag in contentItem.Tags)
					{
						var tagId = _tagModel.GetTag(tag);
						item.OnlineContentTags.Add(new OnlineContentTag {TagId = tagId.Id});
					}
				}

				if (contentItem.TeamDocumentsUrls.Count > 0 && contentItem.TeamDocumentsUrls.Count == contentItem.TeamDocumentsNames.Count)
				{
					for (var i = 0; i < contentItem.TeamDocumentsUrls.Count; i++)
					{
						var url = contentItem.TeamDocumentsUrls[i];
						var name = contentItem.TeamDocumentsNames[i];
						item.TeamDocs.Add(new TeamDoc { Name = name, Url = url });
					}
				}
                item.NeedMoney = needMoney(item.QualityString, item.VideoContentType.ToString(), 
                    item.MaxUsers.HasValue ? item.MaxUsers.Value : 0, 
                    item.MaxHours.HasValue ? item.MaxHours.Value : 0);
				SubmitAllChanges();
			}
		}
        public string [] isStatusChanged(int id, string stat)
        {
            string[] ret = null;
            OnlineContent content = AllContent.SingleOrDefault(x => x.Id == id);
            if (content == null)
            {
                return new string [] {"notfound",""};
            }
            if (stat == "all")
                ret = new string[] 
                {
                    content.OnlineContentType.ToString(),
                    content.Active  ? content.CamParam : ".",
                    content.Likes.ToString(),
                    content.UnLikes.ToString(),
                    content.Views_anonce.ToString(),
                    content.Views_online.ToString(),
                    content.Views_history.ToString(),
                    content.View_current.ToString(),
                    "$" + content.CollectedMoney.ToString("0.00").Replace(",", ".").Replace(".00", ""),
                  // content.CollectedMoney.ToString(
                    //VideoSeller.Business.Extensions.ResourceExtension.GetCurrencyString(content.CollectedMoney),
                    string.Format(" (-{0:0})",content.CollectedMoneyExt),
                    content.broadcastStart.ToString("dd MMM yyyy HH:mm"),
                    content.Claims.ToString()
                   
                   
                };
            else
                ret = new string[] { 
                    content.OnlineContentType.ToString(),
                    content.Active ? content.CamParam : "."
                };
            return ret;
        }
		public void DeleteContent(int id)
		{
            var content = AllContent.SingleOrDefault(x => x.Id == id);
			var waitModel = IoC.Resolve<WaitModel>();
			var paidModel = IoC.Resolve<PaidModel>();
            // VD ---------------------------------------------
            if (content != null && content.State > -1)
            {
                if (content.ViewCntA > 0 || content.ViewCntH > 0)
                {
                    content.State = -1;
                    SubmitAllChanges();
                    return;
                }
            }
            // end VD
			if (content != null)
			{
				_onlineCategorizationModel.DeleteAll(content.OnlineCategorizations);
				_onlineRatingModel.DeleteAll(content.OnlineRatings);
				_teamChatModel.DeleteAll(content.TeamChats);
				_teamDocsModel.DeleteAll(content.TeamDocs);
                try
                {

                    _onlineContentClaimModel.DeleteAll(content.OnlineContentClaims);
                }
                catch
                {
                }
				paidModel.DeleteAll(content.Paids);
				waitModel.DeleteAll(content.Waits);
				_tagModel.DeleteAll(content.OnlineContentTags);
                try
                {
                    foreach (var item in content.OnlineContentPlays)
                    {
                        var entity = DataContext.OnlineContentPlays.SingleOrDefault(x => x.ID == item.ID);
                        if (entity != null)
                        {
                            DataContext.OnlineContentPlays.DeleteOnSubmit(entity);
                        }
                    }
                    SubmitAllChanges();
                }
                catch
                {
                }
                try
                {
                    foreach (var item in content.OnlineContentHistories)
                    {
                        var entity = DataContext.OnlineContentHistories.SingleOrDefault(x => x.Id == item.Id);
                        if (entity != null)
                        {
                            DataContext.OnlineContentHistories.DeleteOnSubmit(entity);
                        }
                    }
                    SubmitAllChanges();
                }
                catch
                { }
				Delete(content);
			}
		}

        private void UpdateAnnouncement()
        {

            var announcementWaitingTime = _databaseSettingsProvider.AnnouncementWaitingTime;
            var MaxInactiveOnlineInMinutes = _databaseSettingsProvider.MaxInactiveOnlineInMinutes;
            //foreach (var item in AllContent.Where(x => x.BroadcastType == (short)BroadcastType.Automatically && !x.Active && x.DownloadUrl == null && x.BroadcastStart.HasValue && x.BroadcastStart.Value <= DateTime.Now))
            //{
            //	item.Active = true;
            //}

            foreach (var item in AllContent.Where(x => x.BroadcastType == (short)BroadcastType.Manually && !x.Active && x.DownloadUrl == null &&
                    x.BroadcastStart.HasValue && (DateTime.Now - x.BroadcastStart.Value).Hours >= announcementWaitingTime))
            {
                DeleteContent(item.Id);
            }
            SubmitAllChanges();
            foreach (var item in AllContent.Where(x =>  x.Active && x.BroadcastEnd.HasValue &&
                (DateTime.Now - x.BroadcastEnd.Value).TotalMinutes >= MaxInactiveOnlineInMinutes))
            {
                item.Active = false;
                if (item.AutoHistory == null || !item.AutoHistory.Value)
                {

                    item.State = -1;
                }
            }
            SubmitAllChanges();
        }
        public void cancelPublishing(String id)
        {
            int ID = 0;
            try
            {
                ID= int.Parse(id);
            }
            catch
            { }
            stopPublishing(ID);

        }
        public void stopPublishing(int ID)
        {
            if (ID > 0)
            {
                OnlineContent c = AllContent.Where(m => m.Id == ID).FirstOrDefault();
                if (c != null)
                {
                    c.Active = false;
                    if (c.AutoHistory == null || !c.AutoHistory.Value)
                    {

                        c.State = -1;
                    }
                    SubmitAllChanges();
                }
                
            }

        }
        public void setNotTranslated(int ID)
        {
            if (ID > 0)
            {
                OnlineContent c = AllContent.Where(m => m.Id == ID).FirstOrDefault();
                if (c != null)
                {
                    c.Active = false;
                    c.State = 0;
                    c.BroadcastEnd = null;
                    c.BroadcastStart = DateTime.Now.AddHours(2);
                    c.DownloadUrl = null;
                    c.CamParam = null;
                    SubmitAllChanges();
                }

            }

        }
		public void addView(String id, String userId, String tp)
		{
            try
            {
                

                String idd = id;
                if (id.Contains("_"))
                    idd = id.Substring(0, id.IndexOf('_'));
                if (idd.Contains("."))
                    idd = idd.Substring(0, idd.IndexOf('.'));
                int onlineContentId = 0;
                try
                {
                    onlineContentId = int.Parse(idd);
                }
                catch
                { }
                if (onlineContentId == 0)
                    return;
                OnlineContent item = AllContent.SingleOrDefault(x => x.Id == onlineContentId);
                if (item == null)
                    return;


                if (item.Client.UserId.ToString().ToUpper() == userId.ToUpper())
                    return;

                switch (tp)
                {
                    case "A":
                        item.ViewCntA = item.ViewCntA == null ? 1 : item.ViewCntA + 1;
                        break;
                    case "O":
                        item.ViewCnt = item.ViewCnt == null ? 1 : item.ViewCntA + 1;
                        break;
                    case "H":
                        item.ViewCntH = item.ViewCntH == null ? 1 : item.ViewCntH + 1;
                        break;
                }
                SubmitAllChanges();
            }
            catch
            {
            }
		}
	}
}